package com.sakiko.config;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * projectName: com.sakiko.config
 *
 * @author: Yang
 * description: 注册两个回调函数，处理确认结果、处理回退结果
 * time: 2025/8/16 21:32
 */
@Slf4j
//@Configuration
@Component
public class MQProducerAckConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @PostConstruct // 当前对象被 ioc容器初始化后，再通过这个方法继续初始化
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    /**
     * 处理确认回调: 交换机有没有收到消息，都会执行此回调
     *
     * @param correlationData 退回的关联数据 (发送信息时，如果携带了关联数据，会被回退)
     * @param ack             true => 交换机收到了消息，false => 交换机没收到
     * @param cause           ack = false => 会返回原因，一般指的是异常
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        System.out.println("correlationData = " + correlationData);
        if (ack)
            System.out.println("交换机收到消息了，ack = " + ack);
        else
            System.out.println("交换机没收到消息，cause = " + cause);
    }

    // 交换机到队列的失败回调: 找不到队列回退
    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.info("消息主体: " + new String(returned.getMessage().getBody()));
        log.info("应答码: " + returned.getReplyCode());
        log.info("描述：" + returned.getReplyText());
        log.info("消息使用的交换器 exchange : " + returned.getExchange());
        log.info("消息使用的路由键 routing : " + returned.getRoutingKey());
    }
}
